package com.log.fenxi;

import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.common.io.FileWriteMode;
import com.google.common.io.Files;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author carter
 * create time    2018-07-20
 */
public class AvgTime {

    public static void main(String[] args) throws IOException {

        String fileDay = "20180720";
        String fileName  = "d:/".concat(fileDay).concat(".txt");
        File file = new File(fileName);

        if (!file.exists())
        {
            System.out.println("文件不存在");
            return;
        }

        List<String> lines = Files.readLines(file, Charsets.UTF_8);

        if (Objects.isNull(lines) || lines.isEmpty())
        {
            System.out.println("文件中没有数据");
            return;
        }

        System.out.println("文件名："+fileName+"\r\n");


        LocalDate fileDayLocalDate = LocalDate.parse(fileDay, DateTimeFormatter.ofPattern("yyyyMMdd"));


        List<LogRecord> logRecordList = lines.stream().map(line -> {

            String[] split = StringUtils.split(line, " ");
            String timeString = split[4].substring(1);
            LocalDateTime dateTime = LocalDateTime.parse(timeString, DateTimeFormatter.ofPattern("dd/MMM/uuuu:HH:mm:ss", Locale.US));
            String url = split[7];

            long request_time = getRequest_time(line, split);

            String day = dateTime.toLocalDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            String add_time = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String module = getModule(url);
            String end_fix = getEndFix(url);

            line = null;
            return new LogRecord(day, add_time, url, request_time, module, end_fix);

        }).filter(item -> item.getRequest_time() > 0 &&
                !Strings.isNullOrEmpty(item.getUrl()) &&
                !Strings.isNullOrEmpty(item.getModule()) &&
                !Strings.isNullOrEmpty(item.getEnd_fix())).collect(Collectors.toList());


        System.out.println("总记录数量："+ logRecordList.size());

        List<List<LogRecord>> taskList = org.apache.commons.collections4.ListUtils.partition(logRecordList,10*10000);



        String saveFileName = fileName.substring(fileName.indexOf("/")+1,fileName.indexOf("."))+".sql";
        File to = new File("d:/log_fenxi/insert" + saveFileName);
        try {
            if (to.exists())
            {
                to.delete();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

         String deleteStrin  = "delete from t_access_time where day='"+fileDayLocalDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+"';";
         deleteStrin+=" INSERT INTO t_access_time(day, add_time, url, request_time, module, end_fix) VALUES ";
        Files.asCharSink(to, Charset.forName("gbk"), FileWriteMode.APPEND).write(deleteStrin);

        for (List<LogRecord> task : taskList)
        {

            StringBuffer stringBuffer = new StringBuffer();


            task.stream().parallel().forEach(item->{

                stringBuffer.append("('").append(item.getDay()).append("','");
                stringBuffer.append(item.getAdd_time()).append("','");
                stringBuffer.append(item.getUrl()).append("',");
                stringBuffer.append(item.getRequest_time()).append(",'");
                stringBuffer.append(item.getModule()).append("','");
                stringBuffer.append(item.getEnd_fix()).append("'),");
                item = null;

            });
            Files.asCharSink(to, Charset.forName("gbk"), FileWriteMode.APPEND).write(stringBuffer.toString());
            task = null;

        }












    }

    public static long getRequest_time(String line, String[] split) {
        long request_time = 0;
        try {
            String timeCostString = split[split.length - 3];
            if (timeCostString.endsWith(","))
            {
                timeCostString = timeCostString.substring(0,timeCostString.length()-1);
            }
            request_time = new BigDecimal(timeCostString).multiply(new BigDecimal(1000)).longValue();
        } catch (NumberFormatException e) {
            System.out.println("出错行信息："+ line );
            request_time = 0;
        }
        return request_time;
    }

    public static String getEndFix(String url) {
        if (Strings.isNullOrEmpty(url))  {
            return "";
        }

        if (!url.contains("."))
        {
            return "java";
        }

       return url.substring(url.lastIndexOf(".")+1);

    }

    public static String getModule(String url) {
        if (Strings.isNullOrEmpty(url))  {
            return "";
        }

        if (url.startsWith("/"))
        {
            String[] split = StringUtils.split(url, "/");
            if (Objects.isNull(split) ||  split.length<1)
            {
                return "";
            }
            String module = split[0];
            int i=1;
            while (Strings.isNullOrEmpty(module) && i<split.length)
            {
                module = split[i];
                i++;
            }
            return  module;
        }

        return "";
    }

    public static void compute(List<UrlTimeModel> urlTimeModelList,String fileName) {

        if (Objects.isNull(urlTimeModelList) || urlTimeModelList.isEmpty())
        {

            System.out.println("数据为空，请检查");
            return;

        }


        StringBuffer stringBuffer = new StringBuffer("INSERT INTO t_access_time(day, add_time, url, request_time, module, end_fix) VALUES ");
//        stringBuffer.append("分析文件"+fileName+"\r\n");
        long totalAvgTime = urlTimeModelList.stream().map(item->item.getTime()).collect(Collectors.averagingLong(value -> value.longValue())).longValue();

//        stringBuffer.append("总的平均响应时间是：" + totalAvgTime +" 总数据条数：" + urlTimeModelList.size()+"\r\n");


        //按照url来计算 平均响应时间， 最大响应时间；
        Map<String, List<UrlTimeModel>> groupModelList = urlTimeModelList.stream().collect(Collectors.groupingByConcurrent(UrlTimeModel::getUrl));

        stringBuffer.append(String.format("%s,%s,%s,%s\r\n","URL", "平均request_time(毫秒)","最大request_time(毫秒)", "总请求次数"));
        groupModelList.entrySet().stream().parallel().map(item->{
            List<UrlTimeModel>  urlTimeList = item.getValue();

            String url = item.getKey();

            //拿到最大的时间；
            Long maxTime = urlTimeList.stream().map(singleU -> singleU.getTime()).collect(Collectors.maxBy(Comparator.comparingLong(value -> value.longValue()))).get();

            //拿到平均的时间；
            long avgTime =  urlTimeList.stream().map(singleU-> singleU.getTime()).collect(Collectors.averagingLong(value -> value.longValue())).longValue();

            Long count = (long)urlTimeList.size();





            return new UrlAvgCountModel(url,avgTime,maxTime,count);
            //总次数


        }).sorted((o1, o2) -> (o2.getAvgTime().intValue() - o1.getAvgTime().intValue())).forEachOrdered(item->{

            stringBuffer.append(String.format("%s,%d,%d,%d\r\n",item.getUrl(), item.getAvgTime(),item.getMaxTime(), item.getCount()));
        });


        System.out.println(stringBuffer.toString());

        try {
            String saveFileName = fileName.substring(fileName.indexOf("/")+1,fileName.indexOf("."))+".csv";
            File to = new File("d:/log_fenxi/分析结果" + saveFileName);
            if (to.exists())
            {
                to.delete();
            }

            Files.write(stringBuffer.toString().getBytes("gbk"), to);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    private static long getTime(String line) {
        return 0;
    }


    public static String getUrl(String line)
    {

        return "";
    }





}
